/**
 * 
 */
package com.eis.sf.in.connector;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import com.eis.sf.in.connector.conf.SFConnParameter;
import com.eis.sf.in.connector.datatype.SFDataType;
import com.eis.sf.in.connector.parameter.SFParameterDefine;
import com.eis.thirdsys.connector.ThirdSysConnector;
import com.eis.thirdsys.connector.conf.ConnectorConfig;
import com.eis.thirdsys.connector.datatype.eissystype.SchemaDefine;
import com.eis.thirdsys.connector.parameter.ParameterValue;
import com.sforce.soap.partner.GetUpdatedResult;
import com.sforce.soap.partner.PartnerConnection;
import com.sforce.soap.partner.sobject.SObject;
import com.sforce.ws.ConnectionException;

/**
 * @author sh-panwei01
 *
 */
public class SFConnector implements ThirdSysConnector {
	private com.sforce.ws.ConnectorConfig config;
	private PartnerConnection connection;
	
	/* (non-Javadoc)
	 * @see com.eis.function.connector.FunctionConnector#init(com.eis.function.connector.conf.ConnectorConfig, com.eis.function.connector.datatype.DataTypeList)
	 */
	public boolean init(ConnectorConfig connectorConfig) throws ConnectionException {
		config = new com.sforce.ws.ConnectorConfig();
		config.setUsername(connectorConfig
				.getOneConf(SFConnParameter.username.name()).getValue());
		config.setPassword(connectorConfig
				.getOneConf(SFConnParameter.password.name()).getValue());
		config.setAuthEndpoint(connectorConfig
				.getOneConf(SFConnParameter.authEndPoint.name()).getValue());
		
		connection = new PartnerConnection(config);
		return true;
	}

	/* (non-Javadoc)
	 * @see com.eis.function.connector.FunctionConnector#getFunctionSchema(java.lang.String, java.lang.String)
	 */
	public ArrayList<HashMap<String, Object>> getFunctionSchema(
			String functionId, String dataFetchId, List<ParameterValue> callParameters) {

		ArrayList<HashMap<String, Object>> returnList = new ArrayList<HashMap<String, Object>>();

		// hard code SFObjId
		HashMap<String, Object> id = new HashMap<String, Object>();
		id.put(SchemaDefine.FIELDNAME.name(), "SFObjId");
		id.put(SchemaDefine.DATATYPE.name(), SFDataType.String.name());
		id.put(SchemaDefine.SCRTEXT_M.name(), "unique id");
		id.put(SchemaDefine.LENG.name(), "128");
		
		returnList.add(id);
		
		for (ParameterValue cp : callParameters) {
			HashMap<String, Object> oneresult = new HashMap<String, Object>();
			if (cp.getElementValue(SFParameterDefine.fieldName.name()) != null) {
				String value = cp.getElementValue(SFParameterDefine.fieldName.name()).getValue();
				if (value != null)  value = value.trim();
				oneresult.put(SchemaDefine.FIELDNAME.name(), value);
			}
			if (cp.getElementValue(SFParameterDefine.fieldName.name()) != null) {
				String value = cp.getElementValue(SFParameterDefine.fieldType.name()).getValue();
				if (value != null)  value = value.trim();
				oneresult.put(SchemaDefine.DATATYPE.name(), value);
			}
			if (cp.getElementValue(SFParameterDefine.fieldName.name()) != null) {
				String value = cp.getElementValue(SFParameterDefine.fieldDisplayName.name()).getValue();
				if (value != null)  value = value.trim();
				oneresult.put(SchemaDefine.SCRTEXT_M.name(), value);
			}
			returnList.add(oneresult);
		}

		return returnList;
	}

	/* (non-Javadoc)
	 * @see com.eis.function.connector.FunctionConnector#getFunctionData(java.lang.String, java.lang.String, java.lang.String, java.util.List)
	 */
	public ArrayList<HashMap<String, Object>> getFunctionData(String functionId, 
			String dataFetchId, 
			Date lastFetchDate, 
			List<ParameterValue> callParameters) throws Exception {
		Date startdate = lastFetchDate;
		Calendar start = Calendar.getInstance();
		start.setTime(startdate);

		Calendar end = Calendar.getInstance();
		
		GetUpdatedResult result = connection.getUpdated(dataFetchId.trim(), start, end);
		String[] idArray = result.getIds();
		StringBuilder retrieveList = new StringBuilder();
		
		for (ParameterValue cp : callParameters) {
			String fieldName 
				= cp.getElementValue(SFParameterDefine.fieldName.name()).getValue();
			
			if (fieldName != null) {
				retrieveList.append(fieldName.trim()).append(",");
			}
		}
		
		ArrayList<HashMap<String, Object>> returnList = new ArrayList<HashMap<String, Object>>();
		
		if (retrieveList.length() > 0) {
			retrieveList.deleteCharAt(retrieveList.length() - 1);
			SObject[] sObjects = connection.retrieve(retrieveList.toString(),
					dataFetchId.trim(), idArray);
			
			for (SObject so : sObjects) {
				HashMap<String, Object> oneresult = new HashMap<String, Object>();
				oneresult.put("SFObjId", so.getId());
				for (ParameterValue cp : callParameters) {
					String fieldName = cp.getElementValue(SFParameterDefine.fieldName.name()).getValue();
					oneresult.put(fieldName, so.getField(fieldName));
				}
				returnList.add(oneresult);
			}
		}
		
	    return returnList;
	}

	public void dispose() {
	}
}
